package org.example.echoexample;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.time.LocalDateTime;
import java.util.Scanner;

/**
 * @author hh
 * @since 2024/11/2
 */
public class NettyEchoClient {
    private int serverPort;
    private String serverIp;
    Bootstrap b = new Bootstrap();

    public NettyEchoClient(String serverIp, int serverPort) {
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }

    public static void main(String[] args) {
        NettyEchoClient nettyEchoClient = new NettyEchoClient("127.0.0.1", 9999);
        nettyEchoClient.runClient();
    }

    public void runClient() {
        // 创建反应器轮询组
        NioEventLoopGroup workerLoopGroup = new NioEventLoopGroup();
        try {
            // 设置反应器轮询组
            b.group(workerLoopGroup);
            // 设置NIO类型的通道
            b.channel(NioSocketChannel.class);
            // 设置监听端口
            b.remoteAddress(serverIp, serverPort);
            // 设置通道的参数
            b.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);

            // 装配子通道流水线
            b.handler(new ChannelInitializer<SocketChannel>() {
                // 有连接到达时会创建一个通道
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    // 管理子通道中的Handler
                    // 向子通道流水线添加一个Handler
                    socketChannel.pipeline().addLast(NettyEchoClientHandler.INSTANCE);
                }
            });

            ChannelFuture f = b.connect();
            f.addListener((futureListener) -> {
                if (futureListener.isSuccess()) {
                    System.out.println("客户端连接成功");
                } else {
                    System.out.println("客户端连接失败");
                }
            });

            // 阻塞，直到连接成功
            f.sync();
            Channel channel = f.channel();
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入发送内容：");
            while (scanner.hasNext()) {
                // 获取输入的内容
                String next = scanner.next();
                byte[] bytes = (LocalDateTime.now() + " --> " + next ).getBytes("utf-8");
                // 发送ByteBuf
                ByteBuf byteBuf = channel.alloc().buffer();
                byteBuf.writeBytes(bytes);
                channel.writeAndFlush(byteBuf);
                System.out.println("请输入发送内容：");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 优雅的关闭EventLoopGroup
            // 释放掉所有资源，包括创建的线程
            workerLoopGroup.shutdownGracefully();
        }
    }
}
